/**
 * 标签搜索控件
 * @file TagZone.js
 * @author chuzhenyang(chuzhenyang@baidu.com)
 */

define(function (require) {
    require('esui/TextBox');
    require('./CandidateArea');
    var u = require('underscore');
    var esui = require('esui');
    var lib = require('esui/lib');
    var Control = require('esui/Control');
    var eoo = require('eoo');
    var $ = require('jquery');
    var painters = require('esui/painters');
    var Event = require('mini-event');

    /**
     * 备选词的选择控件
     *
     * @extends {Control}
     * @param {Object} options 初始化参数
     * @constructor
     */
    var TagZone = eoo.create(
        Control,
        {
            /**
             * 控件类型,始终为`"TagZone"`
             *
             * @type {string}
             * @readonly
             * @override
             */
            type: 'TagZone',

            /**
             * 初始化参数
             *
             * @param {Object} [options] 构造函数传入的参数
             * @protected
             * @override
             */
            initOptions: function (options) {
                var properties = {
                    /**
                     * @property {number} [width=400]
                     *
                     * 默认宽度
                     */
                    width: 400,
                    /**
                     * @property {number} [height=200]
                     *
                     * 默认高度
                     */
                    height: 200,
                    /**
                     * @property {Array} [datasource=['']]
                     *
                     * CandidateArea的数据源
                     */
                    datasource: [],
                    /**
                     * @property {String} [noDataText='无候选词汇']
                     *
                     * CandidateArea被选中的值的集合
                     */
                    selectedValue: []

                };
                u.extend(properties, TagZone.defaultProperties, options);

                this.setProperties(properties);
            },

            /**
             * 初始化DOM结构
             *
             * @protected
             * @override
             */
            initStructure: function () {
                var tpl = [
                    '<div class="${searchClass}">',
                        '<div data-ui-type="TextBox" data-ui-mode="text" data-ui-placeholder="${placeholder}"',
                        ' data-ui-variants="icon-right" data-ui-icon="ui-icon-search"',
                        ' data-ui-width="100%" data-ui-child-name="search" data-ui-height="${searchHeight}"',
                        ' style="margin-bottom:${gap}" data-ui-disabled="${disabled}">',
                        '</div>',
                    '</div>',
                    '<div data-ui-type="CandidateArea" data-ui-repeat="${repeat}" data-ui-disabled="${disabled}"',
                    ' data-ui-no-data-text="${noDataText}" data-ui-child-name="tag" data-ui-height="${tagHeight}">',
                    '</div>'
                ].join('');
                var helper = this.helper;

                // 控件内部padding的大小
                var padding = 5;
                // 搜索框和tag之间的间隔
                var gap = 10;

                this.main.innerHTML = lib.format(
                    tpl,
                    {
                        searchClass: helper.getPartClasses('search'),
                        placeholder: this.placeholder,
                        width: this.width,
                        gap: gap + 'px',
                        disabled: this.disabled,
                        searchHeight: this.searchBoxHeight,
                        tagHeight: this.height - this.searchBoxHeight - padding * 2 - gap,
                        repeat: this.repeat,
                        noDataText: this.noDataText
                    }
                );

                this.initChildren();

                $(this.main).css('padding', padding + 'px');
                // searchBox右侧的搜索icon节点
                var iconNode = $(this.childrenIndex.search.main).find('span');
                iconNode.height(this.searchBoxHeight);
            },

            /**
             * 重渲染
             *
             * @method
             * @protected
             * @override
             */
            repaint: painters.createRepaint(
                Control.prototype.repaint,
                /**
                 * @property {Array} datasource
                 * @property {boolean} repeat
                 * @property {Array} selectedValue
                 *
                 * 数据源,是否允许重复以及选择的值
                 */
                {
                    name: ['datasource', 'repeat', 'selectedValue'],
                    paint: function (zone, datasource, repeat, selectedValue) {
                        var candidateArea = zone.childrenIndex.tag;
                        candidateArea.setProperties({
                            datasource: datasource,
                            repeat: repeat,
                            selectedValue: selectedValue
                        });
                    }
                },
                /**
                 * @property {Number} width
                 * @property {Number} height
                 *
                 * 宽度和高度
                 */
                {
                    name: ['width', 'height'],
                    paint: function (zone, width, height) {
                        $(zone.main).width(width);
                        $(zone.main).height(height);
                    }
                }
            ),

            /**
             * 初始化事件交互
             *
             * @protected
             * @override
             */
            initEvents: function () {
                var searchBox = this.childrenIndex.search;
                var candidateArea = this.childrenIndex.tag;
                // searchBox右侧的搜索icon节点
                var iconNode = $(searchBox.main).find('span');
                var closeClass = this.helper.getIconClass('close');

                // 将candidateArea上的change事件代理给TagZone
                Event.delegate(candidateArea, this, 'change', {preserveData: true, syncState: true});

                // 一旦searchBox里面输入了信息,就将search的icon换为'X'号
                searchBox.on('input', function (e) {
                    iconNode.addClass(closeClass);
                });

                // 监听searchBox的回车事件,之后执行搜索
                searchBox.on('enter', u.bind(searchHandler, this));

                // 监听删除Icon的点击事件，之后重置搜索框内部的值以及tag候选区域的datasource
                iconNode.on('click', u.bind(function (e) {
                    iconNode.removeClass(closeClass);
                    searchBox.setValue('');
                    candidateArea.setProperties({datasource: this.datasource});
                }, this));
            },

            /**
             * 添加一个选中值
             *
             * @protected
             * @param {string} value 要选中的值
             */
            addSelected: function (value) {
                this.childrenIndex.tag.addSelected(value);
            },

            /**
             * 取消一个选中值
             *
             * @protected
             * @param {string} value 要选中的值
             */
            removeSelected: function (value) {
                this.childrenIndex.tag.removeSelected(value);
            }
        }
    );

    /**
     * 默认属性值
     *
     * @type {Object}
     * @public
     */
    TagZone.defaultProperties = {
        // 是否允许出现重复标签
        repeat: false,
        // 无搜索结果时显示的文本
        noDataText: '无候选标签',
        // 搜索框的placeholder
        placeholder: '搜索',
        // 搜索框的高度
        searchBoxHeight: 35
    };


    /**
     * 搜索的处理逻辑
     *
     * @param {Event} e 点击事件
     *
     */
    function searchHandler(e) {
        var searchBox = this.childrenIndex.search;

        var filterValue = searchBox.getValue();
        if (typeof filterValue === 'string') {
            filterValue = lib.trim(filterValue);
        }

        var filteSource = u.filter(this.datasource, function (source) {
            return source.indexOf(filterValue) >= 0;
        });

        this.childrenIndex.tag.setProperties({datasource: filteSource});
    }

    esui.register(TagZone);
    return TagZone;
});
